package com.djf.sharding;

import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * 订单按时间分表算法
 * 根据create_time字段按年月分表：
 * 
 * @author djf
 * @since 2024-01-20
 */
public class OrderTimeShardingAlgorithm implements StandardShardingAlgorithm<LocalDateTime> {

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMM");
    
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<LocalDateTime> shardingValue) {
        LocalDateTime createTime = shardingValue.getValue();
        String suffix = createTime.format(FORMATTER);
        String targetTable = "order_" + suffix;
        
        // 检查目标表是否在可用表列表中
        if (availableTargetNames.contains(targetTable)) {
            return targetTable;
        }
        
        // 如果目标表不存在，返回第一个可用表（或者可以抛出异常）
        return availableTargetNames.iterator().next();
    }

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<LocalDateTime> shardingValue) {
        Set<String> result = new HashSet<>();
        
        LocalDateTime lower = shardingValue.getValueRange().lowerEndpoint();
        LocalDateTime upper = shardingValue.getValueRange().upperEndpoint();
        
        // 计算范围内所有可能的表
        LocalDateTime current = lower.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        while (!current.isAfter(upper)) {
            String suffix = current.format(FORMATTER);
            String targetTable = "order_" + suffix;
            
            if (availableTargetNames.contains(targetTable)) {
                result.add(targetTable);
            }
            
            // 移动到下个月
            current = current.plusMonths(1);
        }
        
        return result.isEmpty() ? availableTargetNames : result;
    }

    @Override
    public void init(Properties props) {
        // 初始化配置
    }

    @Override
    public String getType() {
        return "ORDER_TIME";
    }

    @Override
    public Properties getProps() {
        return null;
    }
}